<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Traits\ResponseJson;
use Illuminate\Support\Facades\Log;


class TestController extends Controller
{
    use ResponseJson;

    public function index()
    {
        $amount   = $this->formatCurrency('100.00');
        $param    = [
            'merchant_no'  => env('MERCHANT_NO'),
            'out_trade_sn' => 'DD' . intval(microtime(true) * 1000000),
            'title'        => '商品名称',
            'amount'       => $amount,
            'notify_url'   => 'https://www.baidu.com',
            'return_url'   => 'https://www.97fish.cn',
            'sign_type'    => 'MD5withRsa'
        ];
        $paramStr = $this->buildParamStr($param);//得到签名前字符串
        $signStr = $this->sign($paramStr, env('PRI_KEY'));
        $payParam = array_merge($param, ['sign' => $signStr]);
        $res      = $this->curl(env('PAY_URL') . '/gw-api/deposit/create', $payParam);
        dd($res);
    }

    /**
     * 格式化金额，对应支付协议中“金额在小数点后两位都是0时，会只保留一个0，即如果amount=100.00，则会使用100.0参与签名与验签”
     * @param $amount
     * @return array|string|string[]
     */
    public function formatCurrency($amount)
    {
        // 格式化为两位小数的字符串表示
        $formatted = number_format($amount, 2, '.', '');
//        dd($formatted);

        // 检查小数点后两位是否为 '00'
        if (preg_match('/\.00$/', $formatted)) {
            // 保留一个 0
            return str_replace('.00', '', $formatted);
        }

        // 否则保持不变
        return $formatted;
    }

    /**
     * 组装签名字符串
     * @param $paramArray
     * @return false|string
     */
    public function buildParamStr($paramArray)
    {
        if (empty($paramArray)) {
            return false;
        }
        ksort($paramArray);
        $str = '';
        foreach ($paramArray as $key => $item) {
            if (!empty($item)) {//去掉为空的参数和值
                //将参数名转为小写
                $str .= strtolower($key) . '=' . $item . '&';
            }
        }
        #删除最后一个&符号
        return substr($str, 0, -1);
    }


    /**
     * 生成签名
     */
    public function sign($param_str, $private_key)
    {
        $private_key = "-----BEGIN RSA PRIVATE KEY-----\n" .
            wordwrap($private_key, 64, "\n", true) .
            "\n-----END RSA PRIVATE KEY-----";


        $private_key = openssl_get_privatekey($private_key);
        openssl_sign($param_str, $sign_info, $private_key, OPENSSL_ALGO_MD5);


        return base64_encode($sign_info);
    }


    /**
     * 验证签名是否
     */
    public function verify($param_str, $sign, $public_key)
    {
        $public_key = "-----BEGIN PUBLIC KEY-----\n" .
            wordwrap($public_key, 64, "\n", true) .
            "\n-----END PUBLIC KEY-----";


        $public_key = openssl_get_publickey($public_key);


        $flag = openssl_verify($param_str, base64_decode($sign), $public_key, OPENSSL_ALGO_MD5);


        return $flag;
    }

    public function curl($url, $postFields = null)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_FAILONERROR, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 20);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
        //https 请求
        if (strlen($url) > 5 && strtolower(substr($url, 0, 5)) == "https") {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        }
        curl_setopt($ch, CURLOPT_POST, true);
        $header = array("content-type: application/json; charset=UTF-8");
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postFields));


        $reponse = curl_exec($ch);

        if (curl_errno($ch)) {
            throw new \Exception(curl_error($ch), 0);
        } else {
            $httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            if (200 !== $httpStatusCode) {
                throw new \Exception($reponse, $httpStatusCode);
            }
        }
        curl_close($ch);
        return json_decode($reponse, true);
    }

}
